@page "/TemplatedComponents"

<h1>Templated Components</h1>

<p>Templated components are components that accept one or more UI templates as parameters, which can then be used as part of the component's rendering logic. Templated components allow you to author higher-level components that are more reusable than regular components.</p>

<p>The following table template examples use the template defined in <em>TableTemplate.razor</em>.</p>

<h2>Implicit template parameters</h2>

<p>Component arguments of type <code>RenderFragment&lt;T&gt;</code> passed as elements have an implicit parameter named <code>context</code>.</p>

<pre><code>&lt;TableTemplate Items="pets"&gt;
    &lt;TableHeader&gt;
        &lt;th&gt;ID&lt;/th&gt;
        &lt;th&gt;Name&lt;/th&gt;
    &lt;/TableHeader&gt;
    &lt;RowTemplate&gt;
        &lt;td&gt;@@context.PetId&lt;/td&gt;
        &lt;td&gt;@@context.Name&lt;/td&gt;
    &lt;/RowTemplate&gt;
&lt;/TableTemplate&gt;</code></pre>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

<h2>Explicit template parameters</h2>

<p>You can change the template parameter name using the <code>Context</code> attribute on the child element.</p>

<pre><code>&lt;TableTemplate Items="pets"&gt;
    &lt;TableHeader&gt;
        &lt;th&gt;ID&lt;/th&gt;
        &lt;th&gt;Name&lt;/th&gt;
        &lt;th&gt;TV Show/Movie&lt;/th&gt;
    &lt;/TableHeader&gt;
    &lt;RowTemplate Context="pet"&gt;
        &lt;td&gt;@@pet.PetId&lt;/td&gt;
        &lt;td&gt;@@pet.Name&lt;/td&gt;
    &lt;/RowTemplate&gt;
&lt;/TableTemplate&gt;</code></pre>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate Context="pet">
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

<h2>Generic-typed Components</h2>

<p>Templated components are often generically typed. For example, a generic ListView component can be used to render <code>IEnumerable&lt;T&gt;</code> values. To define a generic component, use the <code>@@typeparam</code> directive to specify type parameters.</p>

<p>The following ListView template examples use the template defined in <em>ListViewTemplate.razor</em>.</p>

<p>Inferred type:</p>

<pre><code>&lt;ListViewTemplate Items="pets"&gt;
    &lt;ItemTemplate Context="pet"&gt;
        &lt;li&gt;@@pet.Name&lt;/li&gt;
    &lt;/ItemTemplate&gt;
&lt;/ListViewTemplate&gt;</code></pre>

<ListViewTemplate Items="pets">
    <ItemTemplate Context="pet">
        <li>@pet.Name</li>
    </ItemTemplate>
</ListViewTemplate>

<p>Explicitly typed (<code>TItem="Pet"</code>):</p>

<pre><code>&lt;ListViewTemplate Items="pets" TItem="Pet"&gt;
    &lt;ItemTemplate Context="pet"&gt;
        &lt;li&gt;@@pet.Name&lt;/li&gt;
    &lt;/ItemTemplate&gt;
&lt;/ListViewTemplate&gt;</code></pre>

<ListViewTemplate Items="pets" TItem="Pet">
    <ItemTemplate Context="pet">
        <li>@pet.Name</li>
    </ItemTemplate>
</ListViewTemplate>

@code {
    private List<Pet> pets = new List<Pet>
    {
        new Pet { PetId = 1, Name = "Rin Tin Tin" },
        new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
        new Pet { PetId = 3, Name = "Fred" },
        new Pet { PetId = 4, Name = "Salem Saberhagen" },
        new Pet { PetId = 5, Name = "Lassie" },
        new Pet { PetId = 6, Name = "Spot" },
        new Pet { PetId = 7, Name = "K-9" }
    };

    private class Pet
    {
        public int PetId { get; set; }
        public string Name { get; set; }
    }
}
